package org.afk.sisy.io;

import java.io.*;
import java.nio.file.*;
import java.nio.file.attribute.*;

public class PathWrapper
{
	private String hash;

	private final Path relativePath;
	private final Path absolutPath;
	private final Path root;
	private final FileTime lastModified;
	private final long size;
	private final boolean directory;

	public PathWrapper(final Path root, final Path file) throws IOException
	{
		this.size = Files.size(file);
		this.lastModified = Files.getLastModifiedTime(file, LinkOption.NOFOLLOW_LINKS);
		this.absolutPath = file;
		this.directory = Files.isDirectory(file, LinkOption.NOFOLLOW_LINKS);
		this.root = root;
		this.relativePath = root.relativize(file);
	}

	public PathWrapper(final String hash, final Path relativePath, final Path file, final Path root, final long lastModified, final long size,
			final boolean directory)
	{
		super();
		this.hash = hash;
		this.relativePath = relativePath;
		this.absolutPath = file;
		this.root = root;
		this.lastModified = FileTime.fromMillis(lastModified);
		this.size = size;
		this.directory = directory;
	}

	@Override
	public boolean equals(final Object obj)
	{
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final PathWrapper other = (PathWrapper) obj;
		if (this.absolutPath == null)
		{
			if (other.absolutPath != null)
				return false;
		}
		else if (!this.absolutPath.equals(other.absolutPath))
			return false;
		if (this.directory != other.directory)
			return false;
		if (this.hash == null)
		{
			if (other.hash != null)
				return false;
		}
		else if (!this.hash.equals(other.hash))
			return false;
		if (this.lastModified == null)
		{
			if (other.lastModified != null)
				return false;
		}
		else if (!this.lastModified.equals(other.lastModified))
			return false;
		if (this.relativePath == null)
		{
			if (other.relativePath != null)
				return false;
		}
		else if (!this.relativePath.equals(other.relativePath))
			return false;
		if (this.root == null)
		{
			if (other.root != null)
				return false;
		}
		else if (!this.root.equals(other.root))
			return false;
		if (this.size != other.size)
			return false;
		return true;
	}

	public Path getAbsolutPath()
	{
		return this.absolutPath;
	}

	public String getHash()
	{
		return this.hash;
	}

	public FileTime getLastModified()
	{
		return this.lastModified;
	}

	public Path getRelativePath()
	{
		return this.relativePath;
	}

	public Path getRoot()
	{
		return this.root;
	}

	public long getSize()
	{
		return this.size;
	}

	@Override
	public int hashCode()
	{
		final int prime = 31;
		int result = 1;
		result = (prime * result) + ((this.absolutPath == null) ? 0 : this.absolutPath.hashCode());
		result = (prime * result) + (this.directory ? 1231 : 1237);
		result = (prime * result) + ((this.hash == null) ? 0 : this.hash.hashCode());
		result = (prime * result) + ((this.lastModified == null) ? 0 : this.lastModified.hashCode());
		result = (prime * result) + ((this.relativePath == null) ? 0 : this.relativePath.hashCode());
		result = (prime * result) + ((this.root == null) ? 0 : this.root.hashCode());
		result = (prime * result) + (int) (this.size ^ (this.size >>> 32));
		return result;
	}

	public boolean isDirectory()
	{
		return this.directory;
	}

	public void setHash(final String hash)
	{
		this.hash = hash;
	}

	@Override
	public String toString()
	{
		final StringBuilder builder = new StringBuilder();
		builder.append("FileWrapper [");
		if (this.root != null)
		{
			builder.append("root=");
			builder.append(this.root);
			builder.append(", ");
		}
		if (this.relativePath != null)
		{
			builder.append("relativePath=");
			builder.append(this.relativePath);
			builder.append(", ");
		}
		if (this.hash != null)
		{
			builder.append("hash=");
			builder.append(this.hash);
			builder.append(", ");
		}
		if (this.lastModified != null)
		{
			builder.append("lastModified=");
			builder.append(this.lastModified);
			builder.append(", ");
		}
		builder.append("size=");
		builder.append(this.size);
		builder.append(", directory=");
		builder.append(this.directory);
		builder.append(", ");
		if (this.absolutPath != null)
		{
			builder.append("absolutPath=");
			builder.append(this.absolutPath);
		}
		builder.append("]");
		return builder.toString();
	}

}
